﻿using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Security.Principal;
using ProjectFootball.Foundation.Interfaces;

namespace ProjectFootball.Foundation.Entities
{
    public abstract class BaseApprovableEntity : BaseEntity, IApprovableEntity
    {
        [Column(Order = 1)]
        [ScaffoldColumn(false)]
        public Guid HeaderKey { get; set; }

        public virtual DateTime EffectiveFrom { get; set; }

        public virtual DateTime EffectiveTo { get; set; }

        [ScaffoldColumn(false)]
        public bool IsPublic { get; set; }

        [ScaffoldColumn(false)]
        public bool IsMarkedForDeletion { get; set; }

        [ScaffoldColumn(false)]
        public bool IsApproved { get; set; }

        [ScaffoldColumn(false)]
        public Guid ApprovalGuid { get; set; }

        [ScaffoldColumn(false)]
        public Guid OwnerUserId { get; set; }

        [ScaffoldColumn(false)]
        public DateTime DateCreated { get; set; }

        [ScaffoldColumn(false)]
        public Guid ModifiedUserId { get; set; }

        [ScaffoldColumn(false)]
        public DateTime DateModified { get; set; }

        //[ScaffoldColumn(false)]
        //[Timestamp]
        //public Byte[] RowVersion { get; set; }

        #region Static methods
        public static TEntity CreateNew<TEntity>(IPrincipal user)
            where TEntity : IApprovableEntity, new()
        {
            return user.IsAdmin() ? CreatePublic<TEntity>(user.GetUserId()) : CreatePrivate<TEntity>(user.GetUserId());
        }

        public static TEntity CreateUnapproved<TEntity>(Guid userId, Guid approvalGuid)
            where TEntity : IApprovableEntity, new()
        {
            return new TEntity()
            {
                PrimaryKey = Guid.NewGuid(),
                IsPublic = true,
                IsMarkedForDeletion = false,
                IsApproved = false,
                ApprovalGuid = approvalGuid,
                OwnerUserId = userId,
                ModifiedUserId = userId,
                DateCreated = DateTime.Now,
                DateModified = DateTime.Now
            };
        }

        public static void Edit(IApprovableEntity entity, Guid userId)
        {
            entity.ModifiedUserId = userId;
            entity.DateModified = DateTime.Now;
        }

        private static TEntity CreatePublic<TEntity>(Guid userId)
            where TEntity : IApprovableEntity, new()
        {
            return new TEntity()
            {
                PrimaryKey = Guid.NewGuid(),
                IsPublic = true,
                IsMarkedForDeletion = false,
                IsApproved = true,
                ApprovalGuid = Guid.NewGuid(),
                OwnerUserId = userId,
                ModifiedUserId = userId,
                DateCreated = DateTime.Now,
                DateModified = DateTime.Now
            };
        }

        private static TEntity CreatePrivate<TEntity>(Guid userId)
            where TEntity : IApprovableEntity, new()
        {
            return new TEntity()
            {
                PrimaryKey = Guid.NewGuid(),
                IsPublic = false,
                IsMarkedForDeletion = false,
                IsApproved = true,
                ApprovalGuid = Guid.NewGuid(),
                OwnerUserId = userId,
                DateCreated = DateTime.Now,
                ModifiedUserId = userId,
                DateModified = DateTime.Now
            };
        }
        #endregion
    }
}
